


# Mask for interrupts 0 - 31 (bits 0 - 31) where 0 means that int has no error
# word and 1 means interrupt with error word
ERROR_WORD_INTERRUPT_LIST = 0x00027d00

.text

handler__:
	pushl	%ds
	pushl	%es
	pushl	%fs
	pushl	%gs

	pushl	%ebp

	pushl	%esi
	pushl	%edi

	pushl	%edx
	pushl	%ecx
	pushl	%ebx
	pushl	%eax

	pushl	%esp
	call	kernelInterruptDispatch
	addl	$4, %esp

	popl	%eax
	popl	%ebx
	popl	%ecx
	popl	%edx

	popl	%edi
	popl	%esi

	popl	%ebp

	popl	%gs
	popl	%fs
	popl	%es
	popl	%ds

	addl	$8, %esp

	iret

#
# Declare interrupt handlers for n interrupt
# vectors starting at vector i.
#

INTERRUPT_ALIGN = 16

.macro handler i n
cli
	/* This macro distinguishes between two versions of ia32 exceptions.
	   One version has error word and the other does not have it.
	   The latter version fakes the error word on the stack so that the
	   handlers can be the same for both types.
	*/
	.iflt \i - 32
		.if (1 << \i) & ERROR_WORD_INTERRUPT_LIST
		.else
			pushl $0
		.endif
	.else
		pushl $0
	.endif

	pushl $(\i)

	jmp	handler__

	.align INTERRUPT_ALIGN

	.if \n - 1
		handler "(\i + 1)", "(\n - 1)"
	.endif
.endm

.align INTERRUPT_ALIGN
IDT_ITEMS = 256

.global kernelInterruptHandlers
kernelInterruptHandlers:
h_start:
	handler 0   64
	handler 64  64
	handler 128 64
	handler 192 64
h_end:

.data
.global kernelInterruptHandlerSize

kernelInterruptHandlerSize: .long (h_end - h_start) / IDT_ITEMS 

